﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.IO;

namespace CodeSet.Reflection.Samples
{
    class CodeDom2
    {
        /// <summary>
        /// 动态生成编译单元
        /// 编译单元：代码的编译单位
        /// </summary>
        /// <returns></returns>
        private CodeCompileUnit GenerateCompileUnit()
        {
            //定义代码的编译单元
            CodeCompileUnit ccUnit = new CodeCompileUnit();

            //生命命名控件
            CodeNamespace cnsSample = new CodeNamespace("Sample");
            ccUnit.Namespaces.Add(cnsSample);

            //定义一个名为DemoClass的类
            CodeTypeDeclaration ctClass = new CodeTypeDeclaration("DemoClass");

            //Definite the entry point of program
            CodeEntryPointMethod cmStart = new CodeEntryPointMethod();

            //Generate Code：System.Console.WriteLine("Hello World");
            CodeMethodInvokeExpression cmieWrite = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("Ststem.Consle"),
                "WriteLine", new CodePrimitiveExpression("Hello World"));

            //Generate Code; System.Console.Read();
            CodeMethodInvokeExpression cmieRead = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),
                "Read");

            cmStart.Statements.Add(cmieWrite);
            cmStart.Statements.Add(cmieRead);

            ctClass.Members.Add(cmStart);

            cnsSample.Types.Add(ctClass);

            cnsSample.Imports.Add(new CodeNamespaceImport("System"));

            return ccUnit;
        }

        /// <summary>
        /// Generate CSharp Code
        /// </summary>
        public void GenerateCSharpCode()
        {
            CSharpCodeProvider csProvider = new CSharpCodeProvider();

            ICodeGenerator cgCode = csProvider.CreateGenerator();

            StreamWriter sw = new StreamWriter("HelloWorld.cs", false);

            cgCode.GenerateCodeFromCompileUnit(GenerateCompileUnit(), sw, new CodeGeneratorOptions());

            sw.Close();
        }

        public CompilerResults CompileCode(string filepath)
        {
            CSharpCodeProvider csProvider = new CSharpCodeProvider();

            CompilerParameters cmParams = new CompilerParameters(new string[] { "System.dll" },
                filepath.Substring(0, filepath.LastIndexOf(".") + 1) + "exe", false);

            cmParams.GenerateExecutable = true;

            CompilerResults crResult = csProvider.CompileAssemblyFromFile(cmParams, filepath);

            return crResult;
        }
    }
}
